import json

from django.conf import settings
from urllib.parse import urlencode, parse_qs
from urllib.request import urlopen
import ssl
context = ssl._create_unverified_context()


"""
抽取代码流程:
1. 分析出 某一部分代码能够实现特定的功能(如果代码重复性较高则可以抽取,或者当一个方法较复杂时可以抽取)
2. 将代码原封不动的复制到一个方法中,根据对应的问题进去修改,如果缺少对应的数据,则可以以传参的方法传递
3. 将复制的代码注释掉,用抽取的代码进行验证
"""""


class QQOauthTool(object):

    def __init__(self, client_id=None, redirect_uri=None, client_secret=None):
        self.client_id = settings.QQ_APP_ID
        self.client_secret = settings.QQ_APP_KEY
        self.redirect_uri = settings.QQ_REDIRECT_URL

    def get_oauth_url(self, state):
        # 获取state
        # state = request.query_params.get('state')

        # base_url最后要添加问号用来拼接参数
        base_url = 'https://graph.qq.com/oauth2.0/authorize?'

        # 组织一个字典,使用这个字典存放参数
        params = {
            'response_type': 'code',
            'client_id': self.client_id,
            'redirect_uri': self.redirect_uri,
            'state': state,
            'scope': 'get_user_info',
        }

        # 需要将字典的参数拼接到base_url中
        # urllib.parse.urlendoce(query)
        # 将query字典转换为url路径中的查询字符串

        auth_url = base_url + urlencode(params)

        return auth_url

    def get_token_by_code(self, code):

        # 准备url,注意添加?
        base_url = 'https://graph.qq.com/oauth2.0/token?'

        params = {
            'grant_type': 'authorization_code',
            'client_id': self.client_id,
            'client_secret': self.client_secret,
            'code': code,
            'redirect_uri': self.redirect_uri,
        }

        url = base_url + urlencode(params)

        # 获取数据
        # 通过url_open来请求url中的数据
        # response = urlopen(url)
        #
        # data = response.read().decode()
        try:
            resp = urlopen(url, context=context)
            data = resp.read().decode()
        except Exception as e:
            print(e)

        dict = parse_qs(data)
        # print(dict)
        access_tokens = dict.get('access_token')
        if access_tokens:
            access_token = access_tokens[0]

        return access_token

    @staticmethod
    def get_openid_by_token(access_token):
        """
        # https://graph.qq.com/oauth2.0/me
        # GET
        # access_token 必须 在Step1中获取到的accesstoken。

        # 返回数据PC网站接入时，获取到用户OpenID，返回包如下：
        # callback( {"client_id":"YOUR_APPID","openid":"YOUR_OPENID"} );
        # openid是此网站上唯一对应用户身份的标识，网站可将此ID进行存储便于用户下次登录时辨识其身份，
        # 或将其与用户在网站上的原有账号进行绑定

        :param access_token: 
        :return: 
        """""
        base_url = 'https://graph.qq.com/oauth2.0/me?'

        params = {
            'access_token': access_token
        }

        url = base_url + urlencode(params)

        # 获取数据
        resp = urlopen(url, context=context)

        data = resp.read().decode()

        print(data)

        # 对获取的数据进行截取
        try:
            dict = json.loads(data[10: -4])
        except Exception:
            raise Exception('数据获取失败')

        print(dict)

        openid = dict.get('openid')

        if openid:
            return openid

        return None
